package com.tripcube.ai.controller;

import com.tripcube.ai.model.dto.MemoryChatDTO;
import com.tripcube.ai.service.MemoryChatService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.messages.Message;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;

import java.util.List;

/**
 * 记忆聊天控制器
 * 
 * @author alander
 */
@Tag(name = "记忆聊天", description = "具有上下文记忆功能的AI聊天接口")
@RestController
@RequestMapping("/ai/memory-chat")
@RequiredArgsConstructor
@Slf4j
public class MemoryChatController {

    private final MemoryChatService memoryChatService;

    /**
     * 处理同步聊天请求
     * 
     * @param request 记忆聊天请求参数，包含查询内容、会话ID等信息
     * @return 聊天响应内容
     */
    @Operation(summary = "同步记忆聊天", description = "发送消息并同步获取具有上下文记忆的AI回复")
    @PostMapping("/send")
    public String chat(
            @Parameter(description = "记忆聊天请求参数", required = true)
            @RequestBody MemoryChatDTO request) {
        log.info("收到聊天请求: 查询={}, 会话ID={}, 角色={}",
                request.getQuery(), request.getConversationId(), request.getRole());
        return memoryChatService.chat(request);
    }

    /**
     * 处理流式聊天请求
     * 
     * @param request 记忆聊天请求参数
     * @param response HTTP响应对象
     * @return 流式聊天响应
     */
    @Operation(summary = "流式记忆聊天", description = "发送消息并以流式方式获取具有上下文记忆的AI回复")
    @PostMapping(value = "/stream", produces = "text/plain;charset=UTF-8")
    public Flux<String> streamChat(
            @Parameter(description = "记忆聊天请求参数", required = true)
            @RequestBody MemoryChatDTO request,
            HttpServletResponse response) {
        response.setCharacterEncoding("UTF-8");
        log.info("收到流式聊天请求: 查询={}, 会话ID={}, 角色={}",
                request.getQuery(), request.getConversationId(), request.getRole());
        return memoryChatService.streamChat(request);
    }

    /**
     * 处理带角色的同步聊天请求
     * 
     * @param request 记忆聊天请求参数，必须包含角色信息
     * @return 聊天响应内容
     */
    @Operation(summary = "角色同步聊天", description = "基于指定角色进行具有上下文记忆的同步AI对话")
    @PostMapping("/send-with-role")
    public String chatWithRole(
            @Parameter(description = "记忆聊天请求参数，需包含角色信息", required = true)
            @RequestBody MemoryChatDTO request) {
        log.info("收到角色聊天请求: 查询={}, 会话ID={}, 角色={}",
                request.getQuery(), request.getConversationId(), request.getRole());
        return memoryChatService.chatWithRole(request, request.getRole());
    }

    /**
     * 处理带角色的流式聊天请求
     * 
     * @param request 记忆聊天请求参数，必须包含角色信息
     * @param response HTTP响应对象
     * @return 流式聊天响应
     */
    @Operation(summary = "角色流式聊天", description = "基于指定角色进行具有上下文记忆的流式AI对话")
    @PostMapping(value = "/stream-with-role", produces = "text/plain;charset=UTF-8")
    public Flux<String> streamChatWithRole(
            @Parameter(description = "记忆聊天请求参数，需包含角色信息", required = true)
            @RequestBody MemoryChatDTO request,
            HttpServletResponse response) {
        response.setCharacterEncoding("UTF-8");
        log.info("收到角色流式聊天请求: 查询={}, 会话ID={}, 角色={}",
                request.getQuery(), request.getConversationId(), request.getRole());
        return memoryChatService.streamChatWithRole(request, request.getRole());
    }

    /**
     * 获取指定会话的历史消息
     * 
     * @param conversationId 会话ID
     * @return 历史消息列表
     */
    @Operation(summary = "获取历史消息", description = "根据会话ID获取该会话的所有历史消息")
    @GetMapping("/messages/{conversationId}")
    public List<Message> getMessages(
            @Parameter(description = "会话ID", required = true)
            @PathVariable String conversationId) {
        log.info("获取会话历史消息: 会话ID={}", conversationId);
        return memoryChatService.getMessages(conversationId);
    }
}

